home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / gcc / ixemul_src.lha / ixemul-41.0 / library / readlink.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  4KB  |  184 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  readlink.c,v 1.1.1.1 1994/04/04 04:30:31 amiga Exp
  20.  *
  21.  *  readlink.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:31  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.2  1992/05/18  12:22:32  mwild
  26.  *  set errno, and only send READLINK packet if the file really is a symlink
  27.  *
  28.  * Revision 1.1  1992/05/14  19:55:40  mwild
  29.  * Initial revision
  30.  *
  31.  */
  32.  
  33. #define KERNEL
  34. #include "ixemul.h"
  35. #include "kprintf.h"
  36.  
  37. #if __GNUC__ != 2
  38. #define alloca __builtin_alloca
  39. #endif
  40.  
  41. #ifndef ERROR_IS_SOFT_LINK
  42. #define ERROR_IS_SOFT_LINK  233
  43. #endif
  44.  
  45. #ifndef ACTION_READ_LINK
  46. #define ACTION_READ_LINK 1024
  47. #endif
  48.  
  49. struct readlink_vec {
  50.   char *buf;
  51.   int bufsize;
  52. };
  53.  
  54. static int a2u(char *buf, char *src);
  55.  
  56. static int
  57. __readlink_func (struct StandardPacket *sp, struct MsgPort *handler,
  58.                  BPTR parent_lock,
  59.              BSTR name,
  60.              struct readlink_vec *rv, int *no_error)
  61. {
  62.   /* this baby uses CSTRings, absolutely unique... */
  63.   unsigned char *np = BTOCPTR (name);
  64.   np[*np + 1] = 0; np++;
  65.  
  66.   sp->sp_Pkt.dp_Type = ACTION_READ_LINK;
  67.   sp->sp_Pkt.dp_Arg1 = parent_lock;
  68.   sp->sp_Pkt.dp_Arg2 = (long) np;
  69.   sp->sp_Pkt.dp_Arg3 = (long) rv->buf;
  70.   sp->sp_Pkt.dp_Arg4 = rv->bufsize;
  71.  
  72.   PutPacket (handler, sp);
  73.   __wait_sync_packet (sp);
  74.  
  75.   *no_error = sp->sp_Pkt.dp_Res1 > 0;
  76.  
  77.   /* this *can't* be a symlink... */
  78.   return 0;
  79. }
  80.  
  81. int 
  82. readlink(char *path, char *buf, int bufsiz)
  83. {
  84.   struct readlink_vec rv;
  85.   struct stat stb;
  86.   int rc;
  87.   
  88.   /* readlink is buggy in the current fs release (37.26 here), in that
  89.      it reports OBJECT_NOT_FOUND if a file is present but not a 
  90.      symbolic link */
  91.   if (lstat (path, &stb) == 0)
  92.     {
  93.       if (S_ISLNK (stb.st_mode))
  94.     {
  95.       rv.buf = alloca(bufsiz);
  96.       rv.bufsize = bufsiz;
  97.   
  98.       rc = __plock (path, __readlink_func, &rv);
  99.       if (rc <= 0)
  100.         {
  101.           errno = __ioerr_to_errno (IoErr ());
  102.           KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  103.         }
  104.           else if (ix.ix_translate_symlinks)
  105.             {
  106.               memcpy(buf, rv.buf, rc);
  107.             }
  108.           else
  109.             {
  110.               int len = a2u(NULL, rv.buf);
  111.               char *p = alloca(len);
  112.  
  113.               a2u(p, rv.buf);
  114.               rc = (len - 1 < bufsiz ? len - 1 : bufsiz);
  115.               memcpy(buf, p, rc);
  116.               if (rc < bufsiz)
  117.                 buf[rc] = '\0';
  118.             }
  119.       return rc > 0 ? rc : -1;
  120.     }
  121.       else
  122.     {
  123.       errno = EINVAL;
  124.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  125.     }
  126.     }
  127.   /* errno should be set already by lstat() */
  128.   return -1;
  129. }
  130.  
  131. static int a2u(char *buf, char *src)
  132. {
  133.   int len = 0;
  134.  
  135.   if (index(src, ':'))
  136.   {
  137.     if (buf)
  138.       buf[len] = '/';
  139.     len++;
  140.     while (*src != ':')
  141.     {
  142.       if (buf)
  143.         buf[len] = *src;
  144.       len++;
  145.       src++;
  146.     }
  147.     src++;
  148.   }
  149.   else
  150.   {
  151.     if (buf)
  152.       buf[len] = '.';
  153.     len++;
  154.   }
  155.   while (*src)
  156.   {
  157.     if (*src == '/')
  158.     {
  159.       if (buf)
  160.         strcpy(buf + len, "/..");
  161.       len += 3;
  162.       src++;
  163.     }
  164.     else
  165.     {
  166.       if (buf)
  167.         buf[len] = '/';
  168.       len++;
  169.       while (*src && *src != '/')
  170.       {
  171.         if (buf)
  172.           buf[len] = *src;
  173.         src++;
  174.         len++;
  175.       }
  176.       if (*src)
  177.         src++;
  178.     }
  179.   }
  180.   if (buf)
  181.     buf[len] = '\0';
  182.   return ++len;
  183. }
  184.